
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using System.Linq;
using System.Linq.Dynamic;
using System.Linq.Expressions;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;

using System.Linq.Dynamic.Core;
 using Microsoft.EntityFrameworkCore;
using DualControl.HazardSources.Authorization;
using DualControl.HazardSources.Dtos;
using Abp.Dapper.Repositories;
using DualControl.RiskPoints.Dtos;
using DualControl.RiskPoints;
using Abp.Runtime.Session;
using Abp.Organizations;
using DualControl.EmergencyMeasures.Dtos;

namespace DualControl.HazardSources
{
    /// <summary>
    /// HazardSource应用层服务的接口实现方法  
    ///</summary>
    [AbpAuthorize(HazardSourceAppPermissions.HazardSource)]
    public class HazardSourceAppService : DualControlAppServiceBase, IHazardSourceAppService
    {
        private readonly IRepository<HazardSource, int> _hazardsourceRepository;

        private readonly IRepository<RiskPoint> _riskpointrepository;

        //部门
        private readonly IRepository<OrganizationUnit, long> _organizationUnitRepository;

        //注入Dapper，实现复杂查询
        private readonly IDapperRepository<HazardSource> _hazardSourcedapperRepository;
        private readonly IHazardSourceManager _hazardsourceManager;

        /// <summary>
        /// 构造函数 
        ///</summary>
        public HazardSourceAppService(IRepository<HazardSource, int> hazardsourceRepository,
            IHazardSourceManager hazardsourceManager,
            IDapperRepository<HazardSource> hazardSourcedapperRepository,
            IRepository<RiskPoint> riskpointrepository,
            IRepository<OrganizationUnit, long> organizationUnitRepository
            )
        {
            _hazardsourceRepository = hazardsourceRepository;
            _hazardsourceManager = hazardsourceManager;
            _hazardSourcedapperRepository = hazardSourcedapperRepository  ;
            _riskpointrepository = riskpointrepository;
            _organizationUnitRepository = organizationUnitRepository;
        }

      
        

        /// <summary>
        /// 使用这个方法
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<RiskPointListDto>> GetPagedRiskPoints(GetRiskPointsInput input)
        {
            //Include中包含的是实体中的导航属性名
            var query = from rp in  _riskpointrepository.GetAll().Include("HazardSources")
                        select rp;
            // TODO:根据传入的参数添加过滤条件

            var riskpointCount = await query.CountAsync();

            var riskpoints = await query
                    .OrderBy(input.Sorting).AsNoTracking()
                    .PageBy(input)
                    .ToListAsync();

            // var riskpointListDtos = ObjectMapper.Map<List <RiskPointListDto>>(riskpoints);
            var riskpointListDtos = riskpoints.MapTo<List<RiskPointListDto>>();

            return new PagedResultDto<RiskPointListDto>(riskpointCount, riskpointListDtos);
        }

        /// <summary>
        /// 获取RiskPoint包含HazardSource的分页列表信息
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<RiskPointHazardSourceListDto>> GetPagedRiskPointHazardSource(GetRiskPointsInput input)
        {

            var tenantid = AbpSession.GetTenantId();
            var query = await _hazardSourcedapperRepository.QueryAsync<RiskPointHazardSourceListDto>("SELECT riskpoints.Id as 'RiskPointId' ,riskpoints.OrganizationUnitId  ,riskpoints.Code, riskpoints.AreaOrSection,riskpoints.WorkTask,riskpoints.Name ,riskpoints.OperationPurpose,hazardsources.Id  as 'HazardSourceId', hazardsources.HazardSourceName from riskpoints LEFT JOIN hazardsources on riskpoints.Id = hazardsources.RiskPointId where riskpoints.TenantId =" + tenantid);

            var riskpointhsazardsourceListDto = query.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();

            return new PagedResultDto<RiskPointHazardSourceListDto>(
                 riskpointhsazardsourceListDto.Count,
                 riskpointhsazardsourceListDto
                );
        }

      

        /// <summary>
        /// 获取HazardSource的分页列表信息,包含风险点及控制措施
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<HazardSourceListDto>> GetPagedHazardSources(GetHazardSourcesInput input)
        {          

           var query = _hazardsourceRepository.GetAll();

            // TODO:根据传入的参数添加过滤条件

            var hazardsourceCount = await query.CountAsync();

            var hazardsources = await query
                    .OrderBy(input.Sorting).AsNoTracking()
                    .PageBy(input)
                    .ToListAsync();

            // var hazardsourceListDtos = ObjectMapper.Map<List <HazardSourceListDto>>(hazardsources);
            var hazardsourceListDtos = hazardsources.MapTo<List<HazardSourceListDto>>();

            return new PagedResultDto<HazardSourceListDto>(
                hazardsourceCount, hazardsourceListDtos
                );
        }


       







        /// <summary>
        /// 通过指定id获取HazardSourceListDto信息
        /// </summary>
        public async Task<HazardSourceListDto> GetHazardSourceByIdAsync(EntityDto<int> input)
        {
            var entity = await _hazardsourceRepository.GetAsync(input.Id);

            return entity.MapTo<HazardSourceListDto>();
        }

        /// <summary>
        /// MPA版本才会用到的方法
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<GetHazardSourceForEditOutput> GetHazardSourceForEdit(NullableIdDto<int> input)
        {
            var output = new GetHazardSourceForEditOutput();
            HazardSourceEditDto hazardsourceEditDto;

            if (input.Id.HasValue)
            {
                var entity = await _hazardsourceRepository.GetAsync(input.Id.Value);

                hazardsourceEditDto = entity.MapTo<HazardSourceEditDto>();

                //hazardsourceEditDto = ObjectMapper.Map<List <hazardsourceEditDto>>(entity);
            }
            else
            {
                hazardsourceEditDto = new HazardSourceEditDto();
            }

            output.HazardSource = hazardsourceEditDto;
            return output;
        }

        //新增作业步骤：一个作业步骤对应HazardSource中的一条记录
        //支持一次新增多条
        //JostStep即为字段HazardSourceName

        public async Task InsertJobSteps(int RiskPointId,string[] JobSteps)
        {
            var tenantid = AbpSession.GetTenantId();

            foreach (var jobstep in JobSteps)
            {
                if (jobstep.Length > 0)
                {
                    var hazardsource = new HazardSource() { RiskPointId = RiskPointId, HazardSourceName = jobstep, TenantId = tenantid, IsDeleted = false };
                    await _hazardSourcedapperRepository.QueryAsync("insert into HazardSources (RiskPointId,HazardSourceName,TenantId,IsDeleted) values (@RiskPointId,@HazardSourceName,@TenantId,@IsDeleted)", hazardsource);
                }
            }
            
        }





        /// <summary>
        /// 添加或者修改HazardSource的公共方法
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task CreateOrUpdateHazardSource(CreateOrUpdateHazardSourceInput input)
        {

            if (input.HazardSource.Id.HasValue)
            {
                await UpdateHazardSourceAsync(input.HazardSource);
            }
            else
            {
                await CreateHazardSourceAsync(input.HazardSource);
            }
        }

        

        /// <summary>
        /// 新增HazardSource
        /// </summary>
        //[AbpAuthorize(HazardSourceAppPermissions.HazardSource_Create)]
        protected virtual async Task<HazardSourceEditDto> CreateHazardSourceAsync(HazardSourceEditDto input)
        {
            //TODO:新增前的逻辑判断，是否允许新增

            var entity = ObjectMapper.Map<HazardSource>(input);
           
            entity = await _hazardsourceRepository.InsertAsync(entity);
            return entity.MapTo<HazardSourceEditDto>();
        }

        /// <summary>
        /// 编辑HazardSource
        /// </summary>
        //[AbpAuthorize(HazardSourceAppPermissions.HazardSource_Edit)]
        protected virtual async Task UpdateHazardSourceAsync(HazardSourceEditDto input)
        {
            //TODO:更新前的逻辑判断，是否允许更新

            var entity = await _hazardsourceRepository.GetAsync(input.Id.Value);

            //input.MapTo(entity);
            //不用自动转换，手动赋值
            //作业步骤
            if (input.HazardSourceName != null)
            {
                entity.HazardSourceName = input.HazardSourceName;
            }
            //风险因素、事故类型、岗位
            if(input.RiskFactor !=null)
            {
                entity.RiskFactor = input.RiskFactor;
            }
            //事故类型有多种，现使用AccidentTypes
            //if(input.AccidentType >0)
            //{
            //    entity.AccidentType = input.AccidentType;
            //}
            //事故类型有多种，现使用AccidentTypes,是字符串
            if (input.AccidentTypes != null)
            {
                entity.AccidentTypes = input.AccidentTypes;
            }

            if (input.PostId>0)
            {
                entity.PostId = input.PostId;
            }
            //风险评估值，级别及颜色本不可以存入数据库，在实体中计算生成，但是为了方便查询不同级别的隐患，现设一字段，可以加索引
            if(input.L>0)
            {
                entity.L = input.L;
            }
            if (input.E > 0)
            {
                entity.E = input.E;
            }
            if (input.C > 0)
            {
                entity.C = input.C;
            }

            float D = 0;
           
            D = input.L * input.E * input.C;
            
            if (D > 320)
            {
                entity.RiskLevel = Common.RiskLevel.Ⅰ级风险;
                entity.RiskColor = Common.RiskColor.Red;
            }
            else if (D >= 160)
            {
                entity.RiskLevel = Common.RiskLevel.Ⅱ级风险;
                entity.RiskColor = Common.RiskColor.Orange;
            }
            else if (D > 70)
            {
                entity.RiskLevel = Common.RiskLevel.Ⅲ级风险;
                entity.RiskColor = Common.RiskColor.Yellow;
            }
            else if (D > 20)
            {
                entity.RiskLevel = Common.RiskLevel.Ⅳ风险;
                entity.RiskColor = Common.RiskColor.Blue;
            }
            else if (D > 0)
            {
                entity.RiskLevel = Common.RiskLevel.Ⅴ级风险;
                entity.RiskColor = Common.RiskColor.Blue;
            }
            // ObjectMapper.Map(input, entity);
            await _hazardsourceRepository.UpdateAsync(entity);
        }



        /// <summary>
        /// 删除HazardSource信息的方法
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        //[AbpAuthorize(HazardSourceAppPermissions.HazardSource_Delete)]
        public async Task DeleteHazardSource(EntityDto<int> input)
        {
            //TODO:删除前的逻辑判断，是否允许删除
            await _hazardsourceRepository.DeleteAsync(input.Id);
        }



        /// <summary>
        /// 批量删除HazardSource的方法
        /// </summary>
        //          [AbpAuthorize(HazardSourceAppPermissions.HazardSource_BatchDelete)]
        public async Task BatchDeleteHazardSourcesAsync(List<int> input)
        {
            //TODO:批量删除前的逻辑判断，是否允许删除
            await _hazardsourceRepository.DeleteAsync(s => input.Contains(s.Id));
        }


        /// <summary>
        /// 导出HazardSource为excel表,等待开发。
        /// </summary>
        /// <returns></returns>
        //public async Task<FileDto> GetHazardSourcesToExcel()
        //{
        //	var users = await UserManager.Users.ToListAsync();
        //	var userListDtos = ObjectMapper.Map<List<UserListDto>>(users);
        //	await FillRoleNames(userListDtos);
        //	return _userListExcelExporter.ExportToFile(userListDtos);
        //}



        //// custom codes

        //// custom codes end

    }
}


